﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.ESB.Adapter;
using Microsoft.Practices.ESB.Exception.Management;
using Microsoft.Practices.ESB.Itinerary;
using Microsoft.Practices.ESB.Itinerary.Services;
using Microsoft.Practices.ESB.Resolver;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.BizTalk.Message.Interop;
using System.Reflection;

namespace BizTalk.ESB.Extensions.MessagingServices
{
    public class EnhanceFileContextProperties : IMessagingService
    {
        private const string _EnhancedFileContextNamespace = @"https://BizTalk.ESB.Extensions.Schemas.EnhancedFILEProperties";
        private const string _BizTalkFileAdapterPropertiesNamespace = @"http://schemas.microsoft.com/BizTalk/2003/file-properties";

        public IBaseMessage Execute(IPipelineContext context, IBaseMessage msg, string resolverString, IItineraryStep step)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            if (msg == null)
                throw new ArgumentNullException("msg");
            if (string.IsNullOrEmpty(resolverString))
                throw new ArgumentException("Resolver must be provided", "resolverString");
            try
            {
                // Parse existing file name property and save parts to enhanced file context
                EventLogger.Write("Current resolver string = " + resolverString);
                ResolverInfo info = ResolverMgr.GetResolverInfo(ResolutionType.Endpoint, resolverString);
                if (!info.Success)
                    throw new RoutingException("Invalid Resolver", resolverString);

                // Get dictionary from resolver and validate
                Dictionary<string, string> resolverDictionary = ResolverMgr.Resolve(info, msg, context);
                if (string.IsNullOrEmpty(resolverDictionary["Resolver.Action"]))
                {
                    throw new RoutingException("Action not provided in Resolver", resolverString);
                }

                var fileNameSeparator = resolverDictionary["Resolver.Action"];
                var receivedFileName = (string) msg.Context.Read("ReceivedFileName", _BizTalkFileAdapterPropertiesNamespace);
                PromoteEnhancedFileContext(msg, fileNameSeparator, receivedFileName);
                
                return msg;
            }
            catch (System.Exception ex)
            {
                EventLogger.Write(MethodInfo.GetCurrentMethod(), ex);
                throw;
            }
        }

        private static void PromoteEnhancedFileContext(IBaseMessage msg, string fileNameSeparator, string receivedFileName)
        {
            if (!string.IsNullOrEmpty(receivedFileName))
            {
                // Split ReceivedFileName into folder and file
                var foldersplitLocation = receivedFileName.LastIndexOf(@"\");
                var folder = receivedFileName.Substring(0, foldersplitLocation);
                var fileName = receivedFileName.Substring(foldersplitLocation + 1);

                // Split extension from file name
                var extensionsplitLocation = fileName.LastIndexOf(@".");
                var fileNameOnly = fileName.Substring(0, extensionsplitLocation);
                var fileExtension = fileName.Substring(extensionsplitLocation + 1);

                // Split filename into parts using delimiter from Resolver.Action
                var filenameParts = fileNameOnly.Split(fileNameSeparator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

                // Promote enhanced file properties to context
                msg.Context.Promote("Folder", _EnhancedFileContextNamespace, folder);
                msg.Context.Promote("FileName", _EnhancedFileContextNamespace, fileNameOnly);
                msg.Context.Promote("FileExtension", _EnhancedFileContextNamespace, fileExtension);

                if (filenameParts.Length <= 10)
                {
                    for (int i = 0; i < filenameParts.Length; i++)
                    {
                        var filenamePart = filenameParts[i];
                        var contextPropertyName = "FileNamePart" + i.ToString();
                        msg.Context.Promote(contextPropertyName, _EnhancedFileContextNamespace, filenamePart);
                    }
                }
            }
        }

        public string Name
        {
            get { return "BizTalk.Core.Itinerary.MessagingServices.EnhanceFileContextProperties"; }
        }

        public bool ShouldAdvanceStep(IItineraryStep step, IBaseMessage msg)
        {
            return true;
        }

        public bool SupportsDisassemble
        {
            get { return false; }
        }
    }
}
